package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.constants.WmNewsMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.threadlocal.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.service.WmNewsTaskService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsTaskService wmNewsTaskService;

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    /**
     * 查询文章列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        //1.非空判断
        dto.checkParam();
        //2.分页查询
        IPage<WmNews> page=new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper= Wrappers.lambdaQuery();
        //2.1 根据状态查询
        if(dto.getStatus()!=null){
            queryWrapper.eq(WmNews::getStatus,dto.getStatus());
        }

        //2.2 根据关键字查询
        if(!StringUtils.isEmpty(dto.getKeyword())){
            queryWrapper.like(WmNews::getTitle,dto.getKeyword());
        }

        //2.3 根据频道id查询
        if(dto.getChannelId()!=null){
            queryWrapper.eq(WmNews::getChannelId,dto.getChannelId());
        }

        //2.4 根据开始和结束时间查询
        if(dto.getBeginPubdate()!=null && dto.getEndPubdate()!=null){
            queryWrapper.between(WmNews::getPublishTime,dto.getBeginPubdate(),dto.getEndPubdate());
        }

        //2.5 根据登录用户id查询
        queryWrapper.eq(WmNews::getUserId, WmThreadLocalUtil.getUser().getId());

        page=super.page(page,queryWrapper);

        //3.返回数据结果
        ResponseResult result=new PageResponseResult(dto.getPage(),dto.getSize(), (int) page.getTotal());
        result.setData(page.getRecords());
        return result;
    }

    /**
     * 保存-修改-提交草稿为一体的方法
     *  主方法
     * @param dto
     * @return
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //1.非空判断
        if(StringUtils.isEmpty(dto.getContent())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"文章内容不可以为空");
        }
        //表示对自动的类型先暂时设置为null
        if(dto.getType()==-1){
            dto.setType(null);
        }

        //2.新增和修改文章wm_news表的操作
        WmNews entity=new WmNews();
        BeanUtils.copyProperties(dto,entity);
        saveOrUpdateWmNews(entity,dto);

        //3.判断是否是草稿，如果是草稿，则以下步骤不再执行
        if(dto.getStatus()==0){
            return ResponseResult.okResult("当前是草稿状态,流程结束");
        }

        //3.5 从内容中抽取出来的图片地址集合
        List<String> imageList = getImageForContent(dto);


        //4.如果不是草稿，则执行关联内容中的图片和文章的关系，新增wm_news_material中间表数据
            //4.1 获取图片地址集合对应的id集合
        contentImageToNews(entity, imageList, (short) 0);

        //5.如果不是草稿，则关联封面中的图片与文章的关系,新增wm_news_material中间表数据
        fengmianImageToNews(dto, entity, imageList, (short) 1);

     /*   //5.5 调用自动审核业务接口,不可以出现，
        wmAutoScanService.autoScanWmNews(entity.getId());*/

        //5.6 远程调用延迟服务的Feign接口添加任务
        wmNewsTaskService.addNewsToTask(entity.getId(),dto.getPublishTime());

        //6.返回数据
        return ResponseResult.okResult("发布文章完成");
    }



    /**
     * 第四个抽取的方法，关联封面图片与文章的关系
     * @param dto
     * @param entity
     * @param imageList
     * @param type
     */
    private void fengmianImageToNews(WmNewsDto dto, WmNews entity, List<String> imageList,Short type) {
        List<String> images = dto.getImages();
        //images有四种情况，第一是单图size=1,第二是多图，size>=3,第三种是无图，size=0,第四种是自动，size=0
        //如果说是前三种情况，直接新增中间表，直接调用contentImageToNews方法
        //如果说是自动的话，
        if(dto.getType()==null){
            //从内容中取出对应的图片作为封面图片
            if(imageList.size()>=1 && imageList.size()<3){
                //认为是单图，则取出第一张作为封面
                images= imageList.stream().limit(1).collect(Collectors.toList());
                entity.setType((short) 1);
            }else if(imageList.size()>=3){
                //认为是多图，则取出前三张作为封面
                images= imageList.stream().limit(3).collect(Collectors.toList());
                entity.setType((short) 3);
            }else{
                //认为是无图
                entity.setType((short) 0);
            }
            //修改wm_news表的type状态值
            entity.setImages(StringUtils.join(images,","));
            super.updateById(entity);
        }
        //新增中间表方法
        this.contentImageToNews(entity,images, type);
    }

    /**
     * 抽取的第三个方法，内容中的图片与文章的关系
     * @param entity
     * @param imageList
     * @param type
     */
    private void contentImageToNews(WmNews entity, List<String> imageList,Short type) {
        if(imageList !=null && imageList.size()>0){
            //获取素材的实体对象
            List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, imageList));
            //获取素材的id集合
            List<Integer> materialIdsList = wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
            //4.2 然后执行批量新增操作
            wmNewsMaterialMapper.saveRelations(materialIdsList, entity.getId(), type);
        }
    }

    /**
     * 抽取的第二个方法，从内容中抽取对应的图片集合
     * @param dto
     * @return
     */
    private List<String> getImageForContent(WmNewsDto dto) {
        List<String>imageForContentList=new ArrayList();

        String content = dto.getContent();
        List<Map> contentList = JSONArray.parseArray(content, Map.class);
        for (Map map : contentList) {
            if(map.get("type").equals("image")){
               imageForContentList.add((String) map.get("value"));
            }
        }
        return imageForContentList;
    }

    /**
     * 第一个抽取的方法，新增或者修改文章
     * @param dto
     */
    private void saveOrUpdateWmNews(WmNews entity,WmNewsDto dto) {

        entity.setUserId(WmThreadLocalUtil.getUser().getId());
        List<String> images = dto.getImages();
        if(images!=null && images.size()>0){
            entity.setImages(StringUtils.join(images, ","));
        }

        if(dto.getId()==null){//新增
            entity.setCreatedTime(new Date());
            super.save(entity);
        }else{//修改
            //删除中间表，根据文章id
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, dto.getId()));
            //修改文章表
            super.updateById(entity);
        }
    }



    /**
     * 文章上下架
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        //1、非空判断
        if(dto.getId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"id为空");
        }

        //2.根据文章id查询文章
        WmNews wmNews = getById(dto.getId());

        //3.判断文章是否存在
        if(wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }

        //4.判断文章状态是否为已发布
        if (wmNews.getStatus()!=9) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"文章状态不是已发布状态，则无权上下架操作");
        }

        //5.修改文章状态值
        wmNews.setEnable(dto.getEnable());
        updateById(wmNews);

        //6.发送消息
        Map map=new HashMap();
        map.put("articleId",wmNews.getArticleId());
        map.put("enable",wmNews.getEnable());
        kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JSON.toJSONString(map));

        return ResponseResult.okResult("文章上下架完成");
    }
}
